// *************************************************************************
//
//                                JOST
//
//               Copyright (C) 2007 by Angelo Corsaro.
//                       <angelo.corsaro@gmail.com>
//                          All Rights Reserved.
//
//   Permission to use, copy, modify, and distribute this software and
//   its  documentation for any purpose is hereby  granted without fee,
//   provided that the above copyright notice appear in all copies and
//   that both that copyright notice and this permission notice appear
//   in  supporting  documentation. I don't make  any  representations
//   about the  suitability  of this  software for any  purpose. It is
//   provided "as is" without express or implied warranty.
//
//
// *************************************************************************
//  
// *************************************************************************
#ifndef _JOST_INTEGRAL_TYPE_HPP_
#define _JOST_INTEGRAL_TYPE_HPP_

#include <string>
#include "jost/Value.hpp"
#include <boost/lexical_cast.hpp>

namespace jost
{
    template <typename T, jost::Value::TypeID TYPE_ID>
    class IntegralType;

    typedef jost::IntegralType<int, jost::Value::INTEGER>        Integer;
    typedef jost::IntegralType<float, jost::Value::REAL>         Real;
    typedef jost::IntegralType<bool, jost::Value::BOOLEAN>       Boolean;
    typedef jost::IntegralType<std::string, jost::Value::STRING> String;

    typedef void* nil_t;
    typedef jost::IntegralType<nil_t, jost::Value::NIL>            Nil;
}

/**
 * The <code>IntegralType</code> provide a basic abstraction for
 * representing JSON integral types such as integer, real, boolean,
 * string, etc.
 *
 * @author Angelo Corsaro <mailto:angelo.corsaro@gmail.com>
 * @version 0.1
 */ 
template <typename T, jost::Value::TypeID TYPE_ID>
class jost::IntegralType :
    public virtual jost::Value
{
public:
    IntegralType(const T& t) throw()
        : jost::Value(TYPE_ID)
        , value_(t) { }
        
    
    
    virtual ~IntegralType() throw() {}

public:
        /*
    inline operator T& () throw() {
        return this->value_;
    }
        */

    inline T& value() throw() {
        return this->value_;
    }
    
  
public:
    virtual std::string serialize() throw() {
        std::string json_serialization;
        try
        {
            json_serialization = 
                boost::lexical_cast<std::string>(this->value_);
        } 
        catch (const boost::bad_lexical_cast&) { }
            
        return json_serialization;
    }
    
    
private:
    T value_;
};

namespace boost 
{
    template<>
    std::string
    lexical_cast<std::string, bool>(const bool& arg);

    template<>
    std::string
    lexical_cast<std::string, std::string>(const std::string& arg);

    template<>
    std::string
    lexical_cast<std::string, jost::nil_t>(const jost::nil_t& arg);
}

#endif /*_JOST_INTEGRAL_TYPE_HPP_*/
